home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Delphi Programmer's Power Pack
/
Delphi Volume 1.iso
/
s_to_z
/
tcontain
/
tcontain.pas
next >
Wrap
Pascal/Delphi Source File
|
1996-09-15
|
18KB
|
657 lines
Unit tContain;
(**************************************************)
(* tObjectList is taken largely from BI's RTL *)
(* modified to use & free tObjects and added *)
(* persistant stream support & *)
(* emulation of BP7's tCollection iteration *)
(* support with ForEach,FirstThat & LastThat *)
(* *)
(* This container class assumes all items are *)
(* derived from tObject *)
(* Limit is still MaxListSize items, for now.. *)
(**************************************************)
(* 95/05 LPL Soft inc *)
(**************************************************)
{********* Parts from ****************************}
{ }
{ Delphi Visual Component Library }
{ }
{ Copyright (c) 1995 Borland International }
{ }
{**************************************************}
(* Send bug reports (with reproducable source) *)
(* LPL Soft : Robert Daignault *)
(* Compuserve: 70302,1653 *)
(* *)
(* Note : This unit is still in Beta version. Use *)
(* at your own risk! *)
(**************************************************)
interface
(**************************************************)
Uses Classes, SysUtils;
type
pObjects = ^tObjects;
TObjects = array[0..MaxListSize - 1] of pointer{tObject};
TObjectList = class(TPersistent)
private
FDestroy : Boolean;
FList : pObjects;
FCount : Integer;
FCapacity: Integer;
(*****************) protected {procedures *****************}
procedure Error; virtual;
procedure Grow; virtual;
procedure Put(Index: Integer; Item: tObject);
function Get(Index: Integer): tObject;
procedure SetCapacity(NewCapacity: Integer);
procedure SetCount(NewCount: Integer);
Function Allocate(Size:LongInt):Pointer;
Procedure FreeItem(AnItem:Pointer); virtual;
(*****************) Public {procedures *****************}
Constructor Create;
Constructor CreateWithOptions(DestroyObjects:Boolean; InitialCapacity:Integer);
destructor Destroy; override;
function AddObject(Item: tObject): Integer; virtual;
(* Clear and Delete are identical. They do not Free each object *)
procedure Clear; virtual;
procedure Delete(Index: Integer);
Procedure DeleteAll;
(* Free procedures first destroy tObjects and then call Delete procedures*)
Procedure FreeAll;
Procedure FreeAt(Index:Integer);
Procedure FreeObject(Item: tObject);
function IndexOf(Item: tObject): Integer;
procedure Insert(Index: Integer; Item: tObject); virtual;
procedure Move(CurIndex, NewIndex: Integer);
procedure Pack;
(***************** Streaming support *****************)
Constructor CreateFromStream(const FileName: string);
Procedure SaveToStream(const FileName:String);
procedure LoadFromStream(const FileName: string);
procedure ReadData(S: TStream); virtual;
procedure WriteData(S: TStream); virtual;
procedure DefineProperties(Filer: TFiler); override;
(***************** Iteration procedures **************)
function First: tObject; virtual;
function Last: tObject; virtual;
Function Next(Item:tObject; Forward:Boolean):tObject; virtual;
(* Action will be called Count times, each with*)
(* one of its contained tObject *)
(* Procedure Action(AnObject:YourClass); far; *)
procedure ForEach(Action: Pointer);
(* Function Test(AnObject:YourClass):Boolean; far; *)
function LastThat(Test: Pointer): tObject;
function FirstThat(Test: Pointer): tObject;
(* ForEach, FirstThat and LastThat iterators
These work exactly like BP7's tCollection methods.
These methods will call their Action or test
parameters for each tObject it contains.
All Iterators assume that Action and test are
<embedded procedures> or functions declared with
the far attribute. Forgetting to put the far
attribute will cause a GPF. Note that there is
no type checking done by the compiler on either
the procedure type or the parameters to Test and
Action.
*)
(* FirstThat and LastThat stop the iteration when Test *)
(* returns TRUE.These functions return the object that *)
(* caused the iteration to stop. The differ only in the*)
(* Iteration order. LastThat processes the list in *)
(* reverse order *)
(***************** Properties **************)
property Capacity: Integer read FCapacity write SetCapacity;
property Items[Index: Integer]: tObject read Get write Put; default;
property Count:Integer read FCount;
Property DestroyObjects:Boolean read FDestroy write FDestroy;
end;
(* Streaming registration support *)
Procedure RegisterClass(const LoadProc,StoreProc:Pointer;Sender:tClass);
Function IsRegistered(AClass:tClass):Boolean;
(**************************************************************************)
implementation
(**************************************************************************)
Uses Consts;
type
tClassName=String[63];
tRegisterRec=Class(tObject)
Obj:tClass; (* Class type *)
DoLoad,
DoStore :Pointer{TStreamProc}; (* This is a pointer because otherwise
a class instance would be required to register*)
Constructor Create(AClass:tClass; Loader,Storer:Pointer);
end;
var ClassRegistry:tStringList;
(**************************************************************************)
Constructor tRegisterRec.Create(AClass:tClass; Loader,Storer:Pointer);
begin
Inherited Create;
Obj:=AClass;
DoLoad:=Loader;
DoStore:=Storer;
end;
(**************************************************************************)
Procedure RegisterClass(const LoadProc,StoreProc:Pointer;Sender:tClass);
begin
ClassRegistry.AddObject(Sender.ClassName,
tRegisterRec.Create(Sender,LoadProc,StoreProc));
end;
Function IsRegistered(AClass:tClass):Boolean;
Var Index:Integer;
begin
Result:=ClassRegistry.Find(AClass.ClassName,Index);
end;
(**************************************************************************)
Function GetRegistration(AName:tClassName):tRegisterRec;
Var Index:Integer;
begin
With ClassRegistry do
If Find(AName,Index)
then Result:=tRegisterRec(Objects[Index])
else Result:=Nil;
end;
Function CreateInstanceByName(const Name:tClassName;Var Loader:Pointer):tObject;
Var R:tRegisterRec;
S:String[63];
begin
Result:=Nil;
R:=GetRegistration(Name);
If R<>Nil
then begin
Result:=R.Obj.Create;
Loader:=R.DoLoad;
end
else Raise EClassNotFound.CreateFmt('Class <%s> not registered',[Name]);
end;
(**************************************************************************)
Constructor tObjectList.Create;
begin
Inherited Create;
FCount:=0;
FCapacity:=0;
FDestroy:=True;
end;
Constructor tObjectList.CreateWithOptions(DestroyObjects:Boolean; InitialCapacity:Integer);
begin
Create;
FDestroy:=DestroyObjects;
SetCapacity(InitialCapacity);
end;
Constructor tObjectList.CreateFromStream(const FileName: string);
begin
Create;
LoadFromStream(FileName);
end;
destructor tObjectList.Destroy;
begin
FreeAll;
Clear;
Inherited Destroy;
end;
function tObjectList.AddObject(Item: tObject): Integer;
begin
Result := FCount;
if Result = FCapacity
then Grow;
FList^[Result] := Item;
Inc(FCount);
end;
(*************************